﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using IQ.BaseWindows;
using IQ.DbBase;
using IQ.WinForms;
using SqlServerAdmin;

namespace IQ.DbA
{
    public partial class FrmSyncData : Form
    {
		#region # Constructor # 
        public FrmSyncData()
        {
            InitializeComponent();
            grdTableList.AutoGenerateColumns = false;
            splGrids.BackColor = FormSettings.ToolBarBackColor;
        }
		#endregion
		
		#region - Private variables - 
        private DataTable dtTableList;
        private SqlCompareTable compareTable = new SqlCompareTable();
        private int indexChange;
        //
        private Color srcColorChange;
        private Color srcColorNE;
        private Color dstColorChange;
        private Color dstColorNE;
        private Dictionary<ToolStripMenuItem, SqlConst.DataChangeAction> miAction = new Dictionary<ToolStripMenuItem, SqlConst.DataChangeAction>();
        #endregion 

		#region - Private methods - 
        private void setObjects()
        {
            compareTable.SetMaxPosition += setMaxPosition;
            compareTable.SetCurrentPosition += setPosition;
        }
        private void setActions()
        {
            string sourceText = compareTable.SourceDb;
            string destText = compareTable.DestinationDb;
            cmsAction.Items[0].Text = "Add to: " + sourceText;
            cmsAction.Items[1].Text = "Update: " + sourceText;
            cmsAction.Items[2].Text = "Delete: " + sourceText;
            //
            cmsAction.Items[3].Text = "Add to: " + destText;
            cmsAction.Items[4].Text = "Update: " + destText;
            cmsAction.Items[5].Text = "Delete: " + destText;
        }
        private void loadTableList()
        {
            dtTableList = DbHelper.Load_Table(SqlQueries.SqlTablesDetail);
            dtTableList.DefaultView.Sort = SqlQueries.Field_TableName;
        }
        private int getSelectedChangeType()
        {
            int changeType = 0;
            if (grdSource.SelectedCells.Count != 0)
            {
                changeType = Convert.ToInt32(grdSource[indexChange, grdSource.SelectedCells[0].RowIndex].Value);
                for (int i = 0; i < grdSource.SelectedCells.Count; ++i)
                {
                    if (changeType != Convert.ToInt32(grdSource[indexChange, grdSource.SelectedCells[i].RowIndex].Value))
                    {
                        changeType = 0;
                        i = grdSource.SelectedCells.Count;
                    }
                }
            }
            return changeType;
        }
        private void compareTables()
        {
            string tableName = grdTableList[ctName.Index, grdTableList.CurrentRow.Index].Value.ToString();            
            if (compareTable.CompareTables(tableName))
            {
                lblSource.Text = compareTable.SourceTableName;
                lblDest.Text = compareTable.DestinationTableName;
                grdSource.Columns.Clear();
                grdSource.DataSource = compareTable.GetChanges();
                indexChange = grdSource.Columns["ChangeType"].Index;
            }
            else
                General.MesDlg(compareTable.LastMessage, 'E');
        }
        private bool connectToServer(string serverName, bool getUserID)
        {
            ConnectionProperties conDest = new ConnectionProperties();
            conDest.Name = serverName;
            if (ServerConnections.Instance.ServerList.ContainsKey(serverName) && !getUserID)
            {
                conDest.SetConnectionString(ServerConnections.Instance.GetServerConnectString(conDest.Name));
            }
            else
            {
                // Get new connection
                frmSetupConnection frmCon = new frmSetupConnection();
                frmCon.Connection = conDest;
                frmCon.ShowDialog();
            }
            string conResult = conDest.TestConnectionString();
            if (conDest.CanConnect)
            {
                compareTable.DestinationConnection = conDest;
                return true;
            }
            else
            {
                // conResult
                if (General.MesDlg("Could not connect to server, try with different " +
                                   " user & password?", 'C') == DialogResult.Yes)
                    return connectToServer(serverName, true);
                else
                    return false;
            }
        }
        private void setMaxPosition(int position)
        {
            pgbCompare.Maximum = position;
        }
        private void setPosition(int position)
        {
            pgbCompare.Value = position;
        }
        private void setMenuItems(SqlConst.DataChangeType changeType)
        {
            // Add
            cmsAction.Items[0].Visible = (changeType == SqlConst.DataChangeType.NotInSource);
            cmsAction.Items[1].Visible = (changeType == SqlConst.DataChangeType.ChangedDestination);
            cmsAction.Items[2].Visible = (changeType != SqlConst.DataChangeType.NotInSource);
            // Destination
            cmsAction.Items[3].Visible = (changeType == SqlConst.DataChangeType.NotInDestination);
            cmsAction.Items[4].Visible = (changeType == SqlConst.DataChangeType.ChangedSource);
            cmsAction.Items[5].Visible = (changeType != SqlConst.DataChangeType.NotInDestination);
        }
        private void actionSelected(SqlConst.DataChangeAction action)
        {
            List<DataRow> drSelected = new List<DataRow>();
            int[] rowIndexes = (from sc in grdSource.SelectedCells.Cast<DataGridViewCell>() select sc.RowIndex).Distinct().ToArray();
            for (int i=0; i < rowIndexes.Length; ++i)
                drSelected.Add(((DataRowView)grdSource.Rows[rowIndexes[i]].DataBoundItem).Row);
            //
            for (int i = 0; i < drSelected.Count; ++i)
            {
                compareTable.ActionChange(drSelected[i], action, rbnIndPk.Checked);
            }
        }
        #endregion

        //#region - Public properties / variables - 
        //#endregion

        //#region - Public methods - 
        //#endregion

        #region - Bind Methods -
        #endregion

        #region - Form Events -
        // This region is for event handler methods that are called without the user knowing about it.
        // Such as the page loading.
        private void frmSyncData_Load(object sender, EventArgs e)
        {
            setObjects();
            srcColorChange = General.ChangeColor(FormSettings.GridRowBC, +20);
            srcColorNE = General.ChangeColor(srcColorChange, +20);
            dstColorChange = General.ChangeColor(FormSettings.GridAlternatingRowBC, +20);
            dstColorNE = General.ChangeColor(dstColorChange, +20);
            lblSrc.BackColor = srcColorChange;
            lblDst.BackColor = dstColorChange;
            // Load Server combox
            cbxServer.Items.Clear();
            foreach (DictionaryEntry entry in ServerConnections.Instance.ServerList)
            {
                cbxServer.Items.Add(entry.Key.ToString());
            }
            // load tables
            if (DbHelper.CanConnect)
            {
                lblBDB.Text = "Database  = " + DbHelper.Database;
                loadTableList();
                grdTableList.DataSource = dtTableList;
            }
        }
        private void grdSource_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
        {
            if (e.RowIndex >= 0 && e.ColumnIndex == indexChange)
            {
                e.Value = SqlConst.GetDataChangeTypeDesc((SqlConst.DataChangeType)grdSource[indexChange, e.RowIndex].Value);
            }            
        }
        private void grdSource_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
        {
            if (e.RowIndex >= 0 && e.ColumnIndex >= 0)
            {
                int changeType = Convert.ToInt32(grdSource[indexChange, e.RowIndex].Value);
                switch (changeType)
                {
                    case (int)SqlConst.DataChangeType.ChangedDestination: e.CellStyle.BackColor = dstColorChange; break;
                    case (int)SqlConst.DataChangeType.ChangedSource: e.CellStyle.BackColor = srcColorChange; break;
                    case (int)SqlConst.DataChangeType.NotInDestination: e.CellStyle.BackColor = srcColorNE; break;
                    case (int)SqlConst.DataChangeType.NotInSource: e.CellStyle.BackColor = dstColorNE; break;
                }
            }
        }
        private void cmsAction_Opening(object sender, CancelEventArgs e)
        {
            int changeType = getSelectedChangeType();
            if (changeType > 0)
            {
                setMenuItems((SqlConst.DataChangeType)changeType);
            }
            else
            {
                General.MesDlg("You can only action records with the same change type, please change selection.", 'I');
                e.Cancel = true;
            }
        }
        #endregion 
		
		#region - Control Methods -
		// This region is for event handler methods that are called knowingly by the user.
		// Such as a button being clicked.
        private void grdTableList_DoubleClick(object sender, EventArgs e)
        {
            compareTables();
        }
        private void btnRun_Click(object sender, EventArgs e)
        {
            compareTables();
        }
        private void cbxDBs_SelectedIndexChanged(object sender, EventArgs e)
        {
            btnConnectD.Image = IQ.DbA.Properties.Resources.RedDot;
        }
        private void cbxServer_SelectedIndexChanged(object sender, EventArgs e)
        {
            btnConnectS.Image = IQ.DbA.Properties.Resources.RedDot;
            btnConnectD.Image = IQ.DbA.Properties.Resources.RedDot;
        }
        private void btnConnectS_Click(object sender, EventArgs e)
        {
            if (connectToServer(cbxServer.Text, false))
            {
                if (String.IsNullOrEmpty(cbxServer.Text))
                    cbxServer.Text = compareTable.DestinationConnection.Name;
                btnConnectS.Image = IQ.DbA.Properties.Resources.GreenDot;
                btnConnectD.Image = IQ.DbA.Properties.Resources.RedDot;
                DataTable datQry = DbHelper.LoadTable(compareTable.DestinationConnection.GetConnectionString(), SqlQueries.SqlDataBases);
                this.cbxDBs.Items.Clear();
                for (int i = 0; i < datQry.Rows.Count; i++)
                {
                    this.cbxDBs.Items.Add(datQry.Rows[i][0].ToString());
                }
                cbxDBs.SelectedIndex = cbxDBs.Items.IndexOf(DbHelper.Database);
            }
            else
            {
                btnConnectS.Image = IQ.DbA.Properties.Resources.RedDot;
            }

        }
        private void btnConnectD_Click(object sender, EventArgs e)
        {
            btnConnectD.Image = IQ.DbA.Properties.Resources.RedDot;
            compareTable.ChangeConnectionDb(cbxDBs.Text);
            compareTable.DestinationConnection.TestConnectionString();
            if (compareTable.DestinationConnection.CanConnect)
            {
                setActions();
                btnConnectD.Image = IQ.DbA.Properties.Resources.GreenDot;
            }
            else
            {
                General.MesDlg("Could not connect to database: " + cbxDBs.Text, 'E');
            }
        }

        private void tmiAction_Click(object sender, EventArgs e)
        {
            ToolStripMenuItem mi = (ToolStripMenuItem)sender;
            if (mi != null)
            {
                SqlConst.DataChangeAction action = SqlConst.DataChangeAction.Update;
                int i = cmsAction.Items.IndexOf(mi);
                switch (i)
                {
                    case 0:
                    case 3: action = SqlConst.DataChangeAction.Add; break;
                    case 1:
                    case 4: action = SqlConst.DataChangeAction.Update; break;
                    case 2:
                    case 5: action = SqlConst.DataChangeAction.Delete; break;
                }
                actionSelected(action);
            }
        }
        private void grdSource_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.ColumnIndex >= 0 && e.RowIndex >= 0 && !grdSource[e.ColumnIndex, e.RowIndex].Selected)
            {
                grdSource.CurrentCell = grdSource[e.ColumnIndex, e.RowIndex];
                grdSource[e.ColumnIndex, e.RowIndex].Selected = true;
            }
        }

        #endregion

    }
}
